﻿/*
** Xin YUAN, 2023, BSD (2)
*/

////////////////////////////////////////////////////////////////////////////////
#ifndef __CTL_MATRIX_H__
#define __CTL_MATRIX_H__
////////////////////////////////////////////////////////////////////////////////

#ifndef __CTL_MDA_H__
	#error matrix.h requires mda.h to be included first.
#endif

////////////////////////////////////////////////////////////////////////////////
namespace CTL {
////////////////////////////////////////////////////////////////////////////////

#pragma pack(push, 1)

//MatrixT<T>
/*! \brief A matrix template class.

A matrix template class.
\tparam T The element type.
*/
template <typename T>
class MatrixT : public MdArray<T, 2>
{
private:
	typedef MdArray<T, 2>  baseClass;

public:
	/*! \brief Constructor.

	Constructor.
	*/
	MatrixT() noexcept
	{
	}
	MatrixT(const MatrixT& src) = delete;
	MatrixT(MatrixT&& src) noexcept : baseClass(rv_forward(static_cast<baseClass&>(src)))
	{
	}
	~MatrixT() noexcept
	{
	}

	MatrixT& operator=(const MatrixT& src) = delete;
	/*! \brief Assignment operator.

	Assignment operator.
	*/
	MatrixT& operator=(MatrixT&& src) noexcept
	{
		baseClass::operator=(rv_forward(static_cast<baseClass&>(src)));
		return *this;
	}

	void SetSize(uintptr_t uRows, uintptr_t uColums)
	{
		assert( uRows > 0 && uColumn > 0 );
		DimInfoT<uintptr_t, 2> dimSizes;
		dimSizes[0] = uColumns;
		dimSizes[1] = uRows;
		DimInfoT<uintptr_t, 2> dimExtras;
		dimExtras[0] = dimExtras[1] = 0;
		baseClass::SetSize(dimSizes, dimExtras);  //may throw
	}

	uintptr_t GetRows() const noexcept
	{
		return baseClass::GetSize()[1];
	}
	uintptr_t GetColumns() const noexcept
	{
		return baseClass::GetSize()[0];
	}

	T* GetPointer() const noexcept
	{
		return MdArrayHelper::GetDataPointer(*this);
	}

	MatrixT<T> Clone()
	{
		return baseClass::Clone();  //may throw
	}
};

#pragma pack(pop)

////////////////////////////////////////////////////////////////////////////////
}
////////////////////////////////////////////////////////////////////////////////
#endif
////////////////////////////////////////////////////////////////////////////////
